package com.jiaanpei.frameproject.modle.net;

import android.content.Context;
import android.util.Log;

import com.jiaanpei.frameproject.R;
import com.jiaanpei.frameproject.app.AppApplication;
import com.jiaanpei.frameproject.utils.Utils;
import com.vise.log.ViseLog;

import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitHelper {
    private static BaseApis baseApis = null;
    private static BaseApis longConnectTimeBaseApis = null;
    public static BaseApis getBaseApis() {
        return baseApis;
    }
    static {
        init();
    }
    private static void init() {

        OkHttpClient okHttpClient = initOkHttpClient();


        baseApis = getApiService(BaseApis.HOST, okHttpClient, BaseApis.class);

        OkHttpClient longConnectTimeOkHttpinitClient = initLongConnectTimeOkHttpinitClient();

        longConnectTimeBaseApis = getApiService(BaseApis.HOST, longConnectTimeOkHttpinitClient, BaseApis.class);

    }

    private static OkHttpClient initOkHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(new LoggingInterceptor());
        setCertificates(AppApplication.getInstance().getApplicationContext(),builder);
        //设置超时
        builder.connectTimeout(30, TimeUnit.SECONDS);
        builder.readTimeout(30, TimeUnit.SECONDS);
        builder.writeTimeout(30, TimeUnit.SECONDS);
        builder.addInterceptor(
                new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("Content-Type", "application/json; charset=UTF-8")
//                              .addHeader("Accept-Encoding", "gzip, deflate")
                                .addHeader("Connection", "keep-alive")
                                .addHeader("Accept", "*/*")
                                .addHeader("Cookie", "add cookies here")
                                .addHeader("Content-Encoding","UTF-8")
                                .addHeader("data","JSON.stringify(strJson)")
                                .addHeader("versionCode", AppApplication.instance==null?"": Utils.getAppVersionName(AppApplication.instance, AppApplication.instance.getPackageName()))

                                .build();

                        return chain.proceed(request);
                    }

                });
        //错误重连
        builder.retryOnConnectionFailure(true);
        return builder.build();
    }
    private static OkHttpClient initLongConnectTimeOkHttpinitClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addInterceptor(new LoggingInterceptor());
        builder.addInterceptor(
                new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("Content-Type", "application/json; charset=UTF-8")
//                                .addHeader("Accept-Encoding", "gzip, deflate")
                                .addHeader("Connection", "keep-alive")
                                .addHeader("Accept", "*/*")
                                .addHeader("Cookie", "add cookies here")
                                .addHeader("Content-Encoding","UTF-8")
                                .addHeader("data","JSON.stringify(strJson)")
                                .addHeader("versionCode", Utils.getAppVersionName(AppApplication.instance, AppApplication.instance.getPackageName()))

                                .build();
                        return chain.proceed(request);
                    }

                });
        //设置超时
        builder.connectTimeout(120, TimeUnit.SECONDS);
        builder.readTimeout(120, TimeUnit.SECONDS);
        builder.writeTimeout(120, TimeUnit.SECONDS);
        //错误重连
        builder.retryOnConnectionFailure(true);

        return builder.build();
    }
    /**
     * 设置ihttps证书验证
     */
    private static void setCertificates(Context context, OkHttpClient.Builder builder) {
        try {
            //将证书导入输入流
            InputStream inputStream = context.getResources().openRawResource(R.raw.jiaanpei);

              /*  //keystore添加证书内容和密码
                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(inputStream, "Picc1234jiaanpei".toCharArray());

                //key管理器工厂
                KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                keyManagerFactory.init(keyStore, "Picc1234jiaanpei".toCharArray());*/

            //构建一个ssl上下文，加入ca证书格式，与后台保持一致
            SSLContext sslContext = SSLContext.getInstance("TLS");
            final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] chain,
                        String authType) throws CertificateException {
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }};


            //参数，添加受信任证书和生成随机数
            //sslContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
            sslContext.init(null, trustAllCerts, new SecureRandom());
            //获得scoket工厂
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            builder.sslSocketFactory(sslSocketFactory);

            //设置ip授权认证：如果已经安装该证书，可以不设置，否则需要设置
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return loggingInterceptor;
    }

    private static <T> T getApiService(String baseUrl, OkHttpClient okHttpClient, Class<T> clz) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();


        T t = retrofit.create(clz);
        return t;

    }
}
